#include "mesh.h"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <QDebug>

Mesh::Mesh() 
    : vbo(QOpenGLBuffer::VertexBuffer)
    , ebo(QOpenGLBuffer::IndexBuffer)
{
}

Mesh::~Mesh()
{
    if (vbo.isCreated())
        vbo.destroy();
    if (ebo.isCreated())
        ebo.destroy();
    if (vao.isCreated())
        vao.destroy();
}

bool Mesh::loadFromFile(const QString& filename)
{
    // 加载模型
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile(filename.toStdString(),
        aiProcess_Triangulate |
        aiProcess_GenNormals |
        aiProcess_FlipUVs);

    if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
        qDebug() << "Assimp error:" << importer.GetErrorString();
        return false;
    }

    // 清除旧数据
    vertices.clear();
    indices.clear();

    // 处理第一个网格（假设只有一个网格）
    if (scene->mNumMeshes > 0) {
        aiMesh* mesh = scene->mMeshes[0];

        // 加载顶点数据
        for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
            Vertex vertex;
            
            // 位置
            vertex.position.setX(mesh->mVertices[i].x);
            vertex.position.setY(mesh->mVertices[i].y);
            vertex.position.setZ(mesh->mVertices[i].z);

            // 法线
            if (mesh->HasNormals()) {
                vertex.normal.setX(mesh->mNormals[i].x);
                vertex.normal.setY(mesh->mNormals[i].y);
                vertex.normal.setZ(mesh->mNormals[i].z);
            }

            vertices.push_back(vertex);
        }

        // 加载索引数据
        for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
            aiFace face = mesh->mFaces[i];
            for (unsigned int j = 0; j < face.mNumIndices; j++) {
                indices.push_back(face.mIndices[j]);
            }
        }

        return true;
    }

    return false;
}

void Mesh::setupMesh()
{
    // 创建并绑定VAO
    QOpenGLContext* context = QOpenGLContext::currentContext();
    if (!context) {
        qDebug() << "无效的OpenGL上下文";
        return;
    }
    
    if (!vao.create()) {
        qDebug() << "创建VAO失败";
        return;
    }
    vao.bind();

    // 创建并填充VBO
    if (!vbo.create()) {
        return;
    }
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices.constData(), vertices.size() * sizeof(Vertex));

    // 创建并填充EBO
    if (!ebo.create()) {
        return;
    }
    ebo.bind();
    ebo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    ebo.allocate(indices.constData(), indices.size() * sizeof(GLuint));

    // 设置顶点属性
    // 位置
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
        reinterpret_cast<void*>(offsetof(Vertex, position)));

    // 法线
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
        reinterpret_cast<void*>(offsetof(Vertex, normal)));

    // 解绑
    vao.release();
    vbo.release();
    ebo.release();

}

void Mesh::render(QOpenGLShaderProgram* program)
{
    if (!program || !vao.isCreated()) {
        return;
    }

    vao.bind();
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
    vao.release();
} 
